package org.fujene.search;

import java.io.IOException;

import org.fujene.communicate.repli.ReplicatePeerSystem;
import org.fujene.logging.LogParser;
import org.fujene.structure.Queue;
import org.fujene.structure.ExtendResult;
import org.fujene.structure.SearchQueue;
import org.msgpack.MessagePackObject;
import org.msgpack.object.ArrayType;
import org.msgpack.object.NilType;
import org.msgpack.object.RawType;
import org.msgpack.rpc.Request;
import org.msgpack.rpc.Server;
import org.msgpack.rpc.loop.EventLoop;

public class ReplicateSearchSystem{
	// Work without executor
	public boolean stopFlag = false;
	public volatile int threadCounter = 0;
	private ReplicatePeerSystem myPeer = null;
	private int port;
	private Server server;

	public ReplicateSearchSystem(ReplicatePeerSystem myPeer, int port){
		this.myPeer = myPeer;
		this.port = port;
	}

	public class SearchRPCHandler{
		public void search(Request req) throws Exception{
			MessagePackObject obj = req.getArguments();
			MessagePackObject[] args = obj.asArray();
			if(args.length < 4
					&& (!args[0].isRawType() || !args[1].isRawType() || !args[2].isIntegerType() || !args[3]
							.isIntegerType())){
				LogParser.severe("Please post appropriate query.");
			}

			try{
				ExtendResult result;
				result = myPeer.setNewSearch(new SearchQueue(args[0].asString(), args[1].asString(), args[2]
						.asInt(), args[3].asInt()));

				MessagePackObject[] objs = new MessagePackObject[result.getLength()];
				int count = 0;
				int i;
				for(Queue eachQueue: result.getQueues()){
					for(i = 0; i < eachQueue.contents.length; i++)
						objs[count++] = RawType.create(eachQueue.contents[i]);
				}
				req.sendResult(ArrayType.create(objs));
			}catch(InterruptedException e){}
		}

		public void stop(Request req){
			this.notifyAll();
			req.sendResult(NilType.create());
		}
	}

	public void initService(){
		EventLoop eventLoop = EventLoop.defaultEventLoop();
		try{
			server = new Server(eventLoop);
			server.serve(new SearchRPCHandler());
			server.listen(port);
//			eventLoop.join();
		}catch(IOException e){}
	}
	
	public void stopService() {
		server.close();
	}
}
